﻿using FPSO.HMI.Utils;
using FPSO.Models.Constant;
using FPSO.Models.Domain;
using FPSO.Services;
using FPSO.Services.Impl;
using FPSO.ViewModel.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace FPSO.HMI.Views.Dialog
{
    /// <summary>
    /// NewTaskDialog.xaml 的交互逻辑
    /// </summary>
    public partial class NewTaskDialog : Window
    {
        private ITankTaskService TaskService;
        private RealOilBallastServiceImpl oilBallastService;
        private UCOilBallastViewModel oilViewModel;
        private int TaskQueueId;
        private List<WBTTask> wTaskList;

        public NewTaskDialog(int queueId, ITankTaskService taskService)
        {
            InitializeComponent();
            TaskService = taskService;
            TaskQueueId = queueId;

            //if (queueId == TaskQueueConstant.UNLOAD_TASK_1_ID)
            //{
            //    //外输
            //    ComboBoxItem outType = new ComboBoxItem() { Content = TaskTypeConstant.UNLOAD_NAME };
            //    ComboBoxItem swapType = new ComboBoxItem() { Content = TaskTypeConstant.SWAP_NAME };
            //    cmbTaskType.Items.Add(outType);
            //    cmbTaskType.Items.Add(swapType);
            //    cmbTaskType.SelectedIndex = 0;

            //    panelWBTTank.Visibility = Visibility.Collapsed;
            //}
            //else
            //{
            //    ComboBoxItem inType = new ComboBoxItem() { Content = TaskTypeConstant.LOAD_NAME };
            //    cmbTaskType.Items.Add(inType);
            //    cmbTaskType.SelectedIndex = 0;
            //}

            //oilViewModel = new UCOilBallastViewModel();
            ////暂时不启用PDB
            //oilBallastService = new RealOilBallastServiceImpl(SysConfig.PDBConnStr, oilViewModel);
            //oilBallastService.ReflushData(DateTime.Now);
            //wTaskList = new List<WBTTask>();
        }

        public static readonly DependencyProperty DialogTitleProperty =
            DependencyProperty.Register("DialogTitle", typeof(string), typeof(NewTaskDialog), new PropertyMetadata("添加任务"));
        public string DialogTitle
        {
            get { return (string)GetValue(DialogTitleProperty); }
            set { SetValue(DialogTitleProperty, value); }
        }

        public void SetSourceTankId(string tankId)
        {
            sourceTank.TankId = tankId;
            try
            {
                if (sourceTank.TankId == "")
                {
                    txbCurVolume.Text = "0";
                }
                else
                {
                    double currentVolum = GetSourceTankCurrentVolume(sourceTank.TankId);
                    double totalVolum = TankConstant.GetTankVolume(sourceTank.TankId);
                    txbCurVolume.Text = Convert.ToInt32(currentVolum * 100 / totalVolum).ToString();
                }
            }
            catch (Exception ex)
            { }
        }


        private void WindowMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                DragMove();
            }
        }

        private void Confirm_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                ValidateValue();

                TankTask task = new TankTask();
                task.TaskQueueId = TaskQueueId;
                task.TaskName = string.Empty;
                task.TaskType = GetTaskType();
                task.TankId = sourceTank.TankId;
                task.TargetVolm = int.Parse(txbTargetVolume.Text);
                task.PipeSpeed = double.Parse(txbPipeSpeed.Text);
                task.TaskState = TaskStateConstant.WATING_ID;
                task.TaskResult = TaskResultConstant.UNEXEC_ID;

                task.SwapTargetTank1 = "";
                if (task.TaskType == TaskTypeConstant.SWAP_ID)
                {
                    task.SwapTargetTank1 = targetTank.TankId;
                }

                task.WBTTaskList = wTaskList;

                task.StartType = TaskStartTypeConstant.START_BY_TIME_ID;
                task.PreTaskId = 0;
                task.PlanStartTime = DateTime.Now;
                double taskHours = CalcEndTime();

                task.PlanEndTime = DateTime.Now.AddHours(taskHours);
                task.ExecStartTime = DateTime.MinValue;
                task.ExecEndTime = DateTime.MinValue;
                task.CreateTime = DateTime.Now;
                task.UpdateTime = DateTime.Now;
                task.DeleteTime = DateTime.MinValue;

                TaskService.AddTask(task);
                //任务添加调用服务计算所有任务相关舱室液位变化情况
                TaskTankCalcService taskTankCalcService = new TaskTankCalcService(TaskService);
                List<TaskTankTimeFlagDetail> res =taskTankCalcService.GetAllTaskTankDetails(null);

                //res 即为计算结果
                this.Close();
            }
            catch(Exception ex)
            {
				CommUtil.AddSystemLog(7, 1, ex.Message);
            }
        }

        private void Cancel_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void Calc_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                ValidateValue();

                //计算任务执行完成各个舱室的状态,没有考虑正在执行的其他任务
                oilBallastService.ReflushData(DateTime.Now);
                //获得当前各个舱室的装载量
                SafeLoadAlgorithmService safeloadAlgorithm = SafeLoadAlgorithmService.GetInstance();
                Dictionary<string, double> volmDic = new Dictionary<string, double>();
                volmDic.Add("NO1_COT_P", oilViewModel.NO1_COT_P.Volume);
                volmDic.Add("NO2_COT_P", oilViewModel.NO2_COT_P.Volume);
                volmDic.Add("NO3_COT_P", oilViewModel.NO3_COT_P.Volume);
                volmDic.Add("NO4_COT_P", oilViewModel.NO4_COT_P.Volume);
                volmDic.Add("NO5_COT_P", oilViewModel.NO5_COT_P.Volume);
                volmDic.Add("NO1_COT_S", oilViewModel.NO1_COT_S.Volume);
                volmDic.Add("NO2_COT_S", oilViewModel.NO2_COT_S.Volume);
                volmDic.Add("NO3_COT_S", oilViewModel.NO3_COT_S.Volume);
                volmDic.Add("NO4_COT_S", oilViewModel.NO4_COT_S.Volume);
                volmDic.Add("NO5_COT_S", oilViewModel.NO5_COT_S.Volume);
                volmDic.Add("NO1_WBT_P", oilViewModel.NO1_WBT_P.Volume);
                volmDic.Add("NO2_WBT_P", oilViewModel.NO2_WBT_P.Volume);
                volmDic.Add("NO3_WBT_P", oilViewModel.NO3_WBT_P.Volume);
                volmDic.Add("NO4_WBT_P", oilViewModel.NO4_WBT_P.Volume);
                volmDic.Add("NO5_WBT_P", oilViewModel.NO5_WBT_P.Volume);
                volmDic.Add("NO1_WBT_S", oilViewModel.NO1_WBT_S.Volume);
                volmDic.Add("NO2_WBT_S", oilViewModel.NO2_WBT_S.Volume);
                volmDic.Add("NO3_WBT_S", oilViewModel.NO3_WBT_S.Volume);
                volmDic.Add("NO4_WBT_S", oilViewModel.NO4_WBT_S.Volume);
                volmDic.Add("NO5_WBT_S", oilViewModel.NO5_WBT_S.Volume);
                volmDic.Add("FPT", oilViewModel.FPT.Volume);
                //根据任务类型，对舱室容量做调整
                int taskType = GetTaskType();
                int targetVolume = int.Parse(txbTargetVolume.Text);
                double targetMaxVolum = TankConstant.GetTankVolume(sourceTank.TankId);
                double targetVolum = (targetMaxVolum * targetVolume / 100);
                if (taskType == TaskTypeConstant.LOAD_ID)
                {
                    //装载任务 ，直接将选定的舱室调整到目标容量
                    volmDic[sourceTank.TankId] = targetVolum;
                }
                else if (taskType == TaskTypeConstant.UNLOAD_ID)
                {
                    //卸载任务 ，直接将选定的舱室调整到目标容量
                    volmDic[sourceTank.TankId] = targetVolum;
                }
                else if (taskType == TaskTypeConstant.SWAP_ID)
                {
                    //倒舱任务
                    double deltaVolum = volmDic[sourceTank.TankId] - targetVolum;
                    if (deltaVolum <= 0)
                    {
                        throw new Exception("倒仓任务的目标容量配置错误");
                    }
                    volmDic[targetTank.TankId] += deltaVolum;
                    volmDic[sourceTank.TankId] = targetVolum;
                }

				//Dictionary<int, double> fullDic = safeloadAlgorithm.GetFullDicByVolumDic(volmDic);
				//ManualCalcResult calcResult = safeloadAlgorithm.CallManualCalc(fullDic);
				ManualCalcResult calcResult = safeloadAlgorithm.CallManualCalc(volmDic,3);
                txbCalc.Text = "横稳心高" + calcResult.ShipCalc.KMT.ToString("0.00");
            }
            catch(Exception ex)
            {
				MessageBox.Show(ex.Message, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private int GetTaskType()
        {
            ComboBoxItem taskType = (ComboBoxItem)cmbTaskType.SelectedItem;
            if (taskType != null)
            {
                string typeContent = taskType.Content.ToString();
                if (typeContent.Equals(TaskTypeConstant.LOAD_NAME))
                {
                    return TaskTypeConstant.LOAD_ID;
                }
                else if (typeContent.Equals(TaskTypeConstant.UNLOAD_NAME))
                {
                    return TaskTypeConstant.UNLOAD_ID;
                }
                else if (typeContent.Equals(TaskTypeConstant.SWAP_NAME))
                {
                    return TaskTypeConstant.SWAP_ID;
                }
            }

            return TaskTypeConstant.DEFAULT_ID;
        }

        private void cmbTaskType_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (GetTaskType() == TaskTypeConstant.SWAP_ID)
            {
                panelTargetTank.Visibility = Visibility.Visible;
            }
            else
            {
                panelTargetTank.Visibility = Visibility.Collapsed;
            }
        }

        private double GetSourceTankCurrentVolume(string tankId)
        {
            List<TankConstant.ConstantTankInfo> constantlists = TankConstant.ConstantList;
            //获取当前选择舱室的容量
            foreach(TankConstant.ConstantTankInfo constant in constantlists)
            {
                string id = constant.TankID;
                if(id == tankId) 
                {
                    return constant.TankVolume;
                }
            }

            return TankConstant.GetTankVolume(sourceTank.TankId);
        }

        private double CalcEndTime()
        {
            double pipeSpeed;
            double.TryParse(txbPipeSpeed.Text, out pipeSpeed);
            double targetVolum;
            double.TryParse(txbTargetVolume.Text, out targetVolum);

            if (!(pipeSpeed <= 0 || targetVolum < 0 || targetVolum > 100 || sourceTank.TankId == ""))
            {
                do
                {
                    double currentVolum = GetSourceTankCurrentVolume(sourceTank.TankId);
                    double totalVolum = TankConstant.GetTankVolume(sourceTank.TankId);
                    double taskVolum = (targetVolum * 0.01 * totalVolum) - currentVolum;
                    int taskType = GetTaskType();
                    if (taskType == TaskTypeConstant.LOAD_ID)
                    {
                        if (taskVolum < 0)
                        {
                            throw new Exception("目标容量小于或等于当前容量,数据不合法!");
                        }
                    }
                    else
                    {
                        if (taskVolum > 0)
                        {
                            throw new Exception("目标容量大于或等于当前容量,数据不合法!");
                        }
                    }

                    double taskHours = Math.Abs(taskVolum) / pipeSpeed;
                    txbEndTime.Text = DateTime.Now.AddHours(taskHours).ToString("yyyy-MM-dd HH:mm:ss");
                    return taskHours;
                } while (false);
            }

            txbEndTime.Text = "";
            return 0;
        }


        private void txbTargetVolume_LostFocus(object sender, RoutedEventArgs e)
        {
            try
            {
                CalcEndTime();
            }
            catch (Exception ex)
            { }
        }

        private void txbPipeSpeed_LostFocus(object sender, RoutedEventArgs e)
        {
            try
            {
                CalcEndTime();
            }
            catch (Exception ex)
            { }
        }
        private void sourceTank_OnTankChanged(int obj)
        {
            try
            {
                if (sourceTank.TankId =="")
                {
                    txbCurVolume.Text = "0";
                }
                else
                {
                    double currentVolum = GetSourceTankCurrentVolume(sourceTank.TankId);
                    double totalVolum = TankConstant.GetTankVolume(sourceTank.TankId);
                    txbCurVolume.Text = Convert.ToInt32(currentVolum * 100 / totalVolum).ToString();
                }

                CalcEndTime();
            }
            catch (Exception ex)
            { }
        }

        private void ValidateValue()
        {
            double pipeSpeed;
            double.TryParse(txbPipeSpeed.Text, out pipeSpeed);
           
            if (pipeSpeed <= 0 && wTaskList.Count<=0)
            {
                throw new Exception("请输入正确的装卸速度!");
            }

            int targetVolume;
            int.TryParse(txbTargetVolume.Text, out targetVolume);


            if ((targetVolume < 0 || targetVolume > 100) && wTaskList.Count <= 0)
            {
                throw new Exception("请输入正确的目标容量!");
            }

            if (sourceTank.TankId == "" && wTaskList.Count <= 0)
            {
                throw new Exception("请设置操作舱室!");
            }

            int taskType = GetTaskType();
            if (taskType == TaskTypeConstant.SWAP_ID)
            {
                //倒舱，需要设置目标舱
                if (targetTank.TankId == "")
                {
                    throw new Exception("请设置倒舱任务的目标舱!");
                }
            }

            double taskHours = CalcEndTime();
            if (taskHours < 2 && wTaskList.Count <= 0)
            {
                throw new Exception("任务执行时间太短");
            }
            if (taskHours > 36 && wTaskList.Count <= 0)
            {
                throw new Exception("任务执行时间太长");
            }
        }

        private void AddWBTTask_Click(object sender, RoutedEventArgs e)
        {
            WBTTaskDialog wbtDialog = new WBTTaskDialog();
            wbtDialog.WindowStartupLocation = WindowStartupLocation.CenterScreen;
            wbtDialog.ShowDialog();
            if (wbtDialog.Result == MessageBoxResult.OK)
            {
                if (wTaskList.Where(t => t.WBTTankId == wbtDialog.WBTId).Count() > 0)
                {
					CommUtil.AddSystemLog(7, 2, wbtDialog.WBTId);
                    return;
                }

                wTaskList.Add(new WBTTask()
                {
                    WBTTankId = wbtDialog.WBTId,
                    PipeSpeed = wbtDialog.WBTSpeed,
                    TargetVolume = wbtDialog.TargetVolume,
                    IsLoad = wbtDialog.TaskType == TaskTypeConstant.LOAD_ID
                });
                ShowWBTTaskList();
            }
        }

        private void EditWBTTask_Click(object sender, RoutedEventArgs e)
        {
            if (wbtTaskList.SelectedItem != null)
            {
                WBTTaskDisplay taskDisplay = (WBTTaskDisplay)wbtTaskList.SelectedItem;
                WBTTaskDialog wbtDialog = new WBTTaskDialog();
                wbtDialog.WindowStartupLocation = WindowStartupLocation.CenterScreen;
                wbtDialog.WBTId = taskDisplay.WBTTankId;
                wbtDialog.WBTSpeed = taskDisplay.PipeSpeed;
                wbtDialog.TargetVolume = taskDisplay.TargetVolume;
                wbtDialog.TaskType = taskDisplay.IsLoad ? TaskTypeConstant.LOAD_ID : TaskTypeConstant.UNLOAD_ID;
                wbtDialog.ShowDialog();
                if (wbtDialog.Result == MessageBoxResult.OK)
                {
                    if (wbtDialog.WBTId != taskDisplay.WBTTankId)
                    {
                        if (wTaskList.Where(t => t.WBTTankId == wbtDialog.WBTId).Count() > 0)
                        {
							CommUtil.AddSystemLog(7, 2, wbtDialog.WBTId);
							return;
                        }
                    }
                    for (int i = 0; i < wTaskList.Count; i++)
                    {
                        if (wTaskList[i].WBTTankId == taskDisplay.WBTTankId)
                        {
                            wTaskList[i].WBTTankId = wbtDialog.WBTId;
                            wTaskList[i].PipeSpeed = wbtDialog.WBTSpeed;
                            wTaskList[i].TargetVolume = wbtDialog.TargetVolume;
                            wTaskList[i].IsLoad = wbtDialog.TaskType == TaskTypeConstant.LOAD_ID;
                            break;
                        }
                    }
                    ShowWBTTaskList();
                }
            }
            else
            {
                MessageBox.Show("请选择需要编辑的压载舱任务!");
            }
        }

        private void DeleteWBTTask_Click(object sender, RoutedEventArgs e)
        {
            if (wbtTaskList.SelectedItem != null)
            {
                WBTTaskDisplay taskDisplay = (WBTTaskDisplay)wbtTaskList.SelectedItem;
                wTaskList = wTaskList.Where(t => t.WBTTankId != taskDisplay.WBTTankId).ToList();
                ShowWBTTaskList();
            }
            else
            {
                MessageBox.Show("请选择需要删除的压载舱任务!");
            }
        }

        private void ShowWBTTaskList()
        {
            List<WBTTaskDisplay> displayList = new List<WBTTaskDisplay>();
            foreach (WBTTask wbt in wTaskList)
            {
                WBTTaskDisplay taskDisplay = new WBTTaskDisplay();
                taskDisplay.WBTTankId = wbt.WBTTankId;
                taskDisplay.WBTTankName = TankConstant.GetTankName(wbt.WBTTankId);
                taskDisplay.PipeSpeed = wbt.PipeSpeed;
                taskDisplay.IsLoad = wbt.IsLoad;
                taskDisplay.TargetVolume = wbt.TargetVolume;   
                taskDisplay.LoadType = wbt.IsLoad ? TaskTypeConstant.LOAD_NAME : TaskTypeConstant.UNLOAD_NAME;
                displayList.Add(taskDisplay);
            }
            wbtTaskList.ItemsSource = displayList;
        }
    }
}
